//
// Created by Tian on 25-5-2.
//

#include "fan_pwm.h"
#include <stdio.h>
#include "driver/ledc.h"
#include "esp_err.h"


// PWM 配置参数
#define LEDC_TIMER              LEDC_TIMER_0
#define LEDC_MODE               LEDC_LOW_SPEED_MODE
#define LEDC_DUTY_RES           LEDC_TIMER_13_BIT // 设置13位分辨率
#define LEDC_FREQUENCY          (8000) // PWM频率5kHz

#define LEDC_OUTPUT_CH0          (48) // 使用GPIO5作为PWM输出
#define LEDC_OUTPUT_CH1          (46)

#define array_size(x) (sizeof(x)/sizeof(x[0]))

const uint8_t pwm_use_io_list[] = {LEDC_OUTPUT_CH0};

void fan_pwm_init(int ch)
{
    // 1. 定时器配置
    ledc_timer_config_t ledc_timer = {
            .speed_mode       = LEDC_MODE,
            .timer_num        = LEDC_TIMER,
            .duty_resolution  = LEDC_DUTY_RES,
            .freq_hz          = LEDC_FREQUENCY,
            .clk_cfg          = LEDC_AUTO_CLK
    };
    ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
    // 2. 通道配置
    ledc_channel_config_t ledc_channel = {
                .speed_mode     = LEDC_MODE,
                .channel        = LEDC_CHANNEL_0,
                .timer_sel      = LEDC_TIMER,
                .intr_type      = LEDC_INTR_DISABLE,
                .gpio_num       = -1, // 没有默认IO
                .duty           = 0, // 初始占空比为0
                .hpoint         = 0
    };

    for (int i = 0; i < array_size(pwm_use_io_list) && i < ch; ++i) {
        ledc_channel.channel = i;
        ledc_channel.gpio_num = pwm_use_io_list[i];
        ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
    }
}

void fan_pwm_set_duty(int channel, int d)
{
    if (channel >= array_size(pwm_use_io_list))
    {
        return;
    }
    if(d > 100)
        d = 100;
    else if(d < 0)
        d = 0;
    uint32_t max_duty = (1 << LEDC_DUTY_RES) - 1; // 计算最大占空比值
    uint32_t cur_duty = (uint32_t)((float )max_duty * ((float )d / 100.0f));

    ESP_ERROR_CHECK(ledc_set_fade_with_time(LEDC_MODE, channel, cur_duty, 200));
    ESP_ERROR_CHECK(ledc_fade_start(LEDC_MODE, channel, LEDC_FADE_WAIT_DONE));
}

void fan_pwm_task(int ch)
{
    if (ch <= 0)
    {
        return;
    }
    // 初始化PWM
    fan_pwm_init(ch);
    // 设置渐变参数
    ledc_fade_func_install(0); // 安装渐变服务

    for (int i = 0; i < ch; ++i) {
        fan_pwm_set_duty(i,0);
    }
}

void fan_pwm_task_init(int max_ch)
{
    fan_pwm_task(max_ch);
    //xTaskCreate(fan_pwm_task, "fan_pwm_task", 4096, NULL, 10, NULL);
}
